﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using EzDesk.DevHelper.DebugLibrary;
using System.Web.Security;
using System.Reflection;
using EzDesk.DevHelper.DebugLibrary.Model;
using EzDesk.DevHelper.DebugLibrary.Helper;
using System.Data.Odbc;
using System.Xml.Linq;

namespace EzDesk.DevHelper.DebugLibrary
{

    public class EzDeskInitial : IEzDeskInitial
    {
        private const string FEED_TEMPLATES_FILENAME = "EzDeskFeedTemplates.xml";
        private const string APP_FUNCTIONS_FILENAME = "EzDeskAppFunctions.xml";

        protected EzDeskDataContext db = new EzDeskDataContext();
        List<IEzDeskInitial> initials = new List<IEzDeskInitial>();


        Guid bossGroupId = Guid.NewGuid();
        Guid hrGroupId = Guid.NewGuid();

        Guid auditLeavePermissionId = Guid.NewGuid();
        Guid hrPermissionId = Guid.NewGuid();

       

        protected void InitialFeedsTemplate(string xmlFileName)
        {
            XElement rootElement = XElement.Load(xmlFileName);
            var feeds = rootElement.Elements();
            foreach (var feed in feeds)
            {
                Guid id = Guid.Empty;
                if (feed.Element("id") != null)
                {
                    id = new Guid(feed.Element("id").Value);
                }
                string templateName = null;
                if (feed.Element("name") != null)
                {
                    templateName = feed.Element("name").Value;
                }
                string title = null;
                if (feed.Element("title") != null)
                {
                    title = feed.Element("title").Value;
                }
                string body = null;
                if (feed.Element("body") != null)
                {
                    body = feed.Element("body").Value;
                }
                int type = 0;
                if (feed.Element("type") != null)
                {
                    type = Int32.Parse(feed.Element("type").Value);
                }
                string templateIcon = "";
                if (feed.Element("templateIcon") != null)
                {
                    templateIcon = feed.Element("templateIcon").Value;
                }

                db.ez_FeedTemplates.InsertOnSubmit(
                    new ez_FeedTemplate()
                    {
                        TemplateName = templateName,
                        TempleId = id,
                        Title = title,
                        Body = body,
                        DefaultType = type,
                        TemplateIcon = templateIcon,
                    }
                    );
            }
            db.SubmitChanges();
        }

        protected void CreateBasicInfo(Guid appId, string name, string title, string description, Dictionary<string, string> domains)
        {
            Debug.WriteLine(string.Format("开始添加 {0} App...", name));
            db.ez_Apps.InsertOnSubmit(
                new ez_App()
                {
                    AppId = appId,
                    Name = name,
                    Description = description,
                    Title = title,
                }
                );
            foreach (var item in domains)
            {
                db.ez_AppDomains.InsertOnSubmit(
                    new ez_AppDomain()
                    {
                        AppId = appId,
                        UserAgentType = item.Key,
                        Domain = item.Value,
                    }
                    );
            }
            db.SubmitChanges();
            Debug.WriteLine(string.Format("{0} App添加成功", name));

        }

        protected void CreatPermissions()
        {
            Debug.WriteLine("开始创建默认包含的权限");

            // 创建 人事管理权限
            ez_Permission hrPermission = new ez_Permission()
            {
                AppName = "ATTENDANCE",
                PermissionId = hrPermissionId,
                Name = "HR_MANAGEMENT",
                DefaultDeny = true,
                Description = "管理员工人事相关的信息",
            };
            db.ez_Permissions.InsertOnSubmit(hrPermission);

            // 创建 人事管理权限
            ez_Permission auditLeavePermission = new ez_Permission()
            {
                AppName = "ATTENDANCE",
                PermissionId = auditLeavePermissionId,
                Name = "AUDIT_LEAVE",
                DefaultDeny = true,
                Description = "审核员工申请的假期",
            };
            db.ez_Permissions.InsertOnSubmit(auditLeavePermission);
            db.SubmitChanges();

            Debug.WriteLine("权限创建结束");


            Debug.WriteLine("开始赋予用户组相应的权限");

            // 人事组 Boss组 拥有人事权限
            ez_Permission_Group hr_hrPermission = new ez_Permission_Group()
            {
                GroupId = hrGroupId,
                PermissionId = hrPermissionId,
                HasPermission = true,
            };
            ez_Permission_Group boss_hrPermission = new ez_Permission_Group()
            {
                GroupId = bossGroupId,
                PermissionId = hrPermissionId,
                HasPermission = true,
            };

            // boss组拥有审核假期权限
            ez_Permission_Group boss_auditLeavePermission = new ez_Permission_Group()
            {
                GroupId = bossGroupId,
                PermissionId = auditLeavePermissionId,
                HasPermission = true,
            };

            db.ez_Permission_Groups.InsertOnSubmit(hr_hrPermission);
            db.ez_Permission_Groups.InsertOnSubmit(boss_hrPermission);
            db.ez_Permission_Groups.InsertOnSubmit(boss_auditLeavePermission);

            db.SubmitChanges();

            Debug.WriteLine("赋予用户组相应的权限结束");
        }

        protected void CreateAppFunctions(string xmlFileName)
        {
            #region [ AppFunction Types ]
            // 创建 AppFunctions 类型

            Debug.WriteLine("开始创建AppFunctionType");
           

            XElement typeElement = XElement.Load(xmlFileName);
            var types = typeElement.Element("Types").Elements();
            foreach (var type in types)
            {
                Guid appFunctionTypeID = Guid.Empty;
                if (type.Element("AppFunctionTypeId") != null)
                {
                    appFunctionTypeID = new Guid(type.Element("AppFunctionTypeId").Value);
                }
                string typeName = "";
                if (type.Element("TypeName") != null)
                {
                    typeName = type.Element("TypeName").Value;
                }
                string displayText = "";
                if (type.Element("DisplayText") != null)
                {
                    displayText = type.Element("DisplayText").Value;
                }
                string iconName = "";
                if (type.Element("IconName") != null)
                {
                    iconName = type.Element("IconName").Value;
                }
                
                int privilege = 0;
                if (type.Element("Privilege") != null)
                {
                    privilege = Int32.Parse(type.Element("Privilege").Value);
                }


                db.ez_AppFunctionTypes.InsertOnSubmit(
                    new ez_AppFunctionType()
                    {
                        AppFunctionTypeId = appFunctionTypeID,
                        TypeName = typeName,
                        DisplayText = displayText,
                        IconName = iconName,
                        Privilege = privilege
                        
                    }
                    );
            }
            db.SubmitChanges();

            Debug.WriteLine("AppFunctionType创建完成");
            #endregion

            #region [ App Functions ]

            Debug.WriteLine("开始创建AppFunctions");
            XElement rootElement = XElement.Load(xmlFileName);
            var functions = rootElement.Element("Functions").Elements();
            foreach (var function in functions)
            {
                Guid appFunctionId = Guid.Empty;
                if (function.Element("AppFunctionId") != null)
                {
                    appFunctionId = new Guid(function.Element("AppFunctionId").Value);
                }
                string appName = "";
                if (function.Element("AppName") != null)
                {
                    appName = function.Element("AppName").Value;
                }
                Guid functionTypeId = Guid.Empty;
                if (function.Element("FunctionTypeId") != null)
                {
                    functionTypeId = new Guid(function.Element("FunctionTypeId").Value);
                }
                Guid functionCategoryId = Guid.Empty;
                if (function.Element("FunctionCategoryId") != null)
                {
                    functionCategoryId = new Guid(function.Element("FunctionCategoryId").Value);
                }
                string title = "";
                if (function.Element("Title") != null)
                {
                    title = function.Element("Title").Value;
                }
                string description = "";
                if (function.Element("Description") != null)
                {
                    description = function.Element("Description").Value;
                }
                string iconName = "";
                if (function.Element("IconName") != null)
                {
                    iconName = function.Element("IconName").Value;
                }
                string funcUrl = "";
                if (function.Element("FuncUrl") != null)
                {
                    funcUrl = function.Element("FuncUrl").Value;
                }
                int privilege = 0;
                if (function.Element("Privilege") != null)
                {
                    privilege = Int32.Parse(function.Element("Privilege").Value);
                }
                string permissionNeed = null;
                if (function.Element("PermissionNeed") != null)
                {
                    permissionNeed = function.Element("PermissionNeed").Value;
                }
                string userAgent = "";
                if (function.Element("UserAgent") != null)
                {
                    userAgent = function.Element("UserAgent").Value;
                }

                db.ez_AppFunctions.InsertOnSubmit(
                    new ez_AppFunction()
                        {
                            AppFunctionId = appFunctionId,
                            AppName = appName,
                            FunctionTypeId = functionTypeId,
                            FunctionCategoryId = functionCategoryId,
                            Title = title,
                            Description = description,
                            IconName = iconName,
                            FuncUrl = funcUrl,
                            Privilege = privilege,
                            PermissionNeed = permissionNeed,
                            UserAgent = userAgent
                        }
                    );
            }
            db.SubmitChanges();

            
            Debug.WriteLine("AppFuncitons创建完成");

            #endregion
        }

        private void ImportBasicDataFromDb()
        {
            CleanupMembershipData();

            Dictionary<string, Guid> positionDict = new Dictionary<string, Guid>();
            Dictionary<string, Guid> deptDict = new Dictionary<string, Guid>();

            string connStr = @"Driver={Microsoft Access Driver (*.mdb)};Dbq=EzDesk.mdb";
            using (OdbcConnection conn = new OdbcConnection(connStr))
            {
                conn.Open();

                // 导入部门
                string sqlStr = "SELECT * FROM dept ";
                OdbcCommand cmd = new OdbcCommand(sqlStr, conn);
                OdbcDataReader dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    Guid newDeptId = Guid.NewGuid();
                    db.ez_Depts.InsertOnSubmit(
                        new ez_Dept()
                        {
                            DeptId = newDeptId,
                            DeptName = dr["dept"] as string,
                        }
                        );
                    deptDict.Add(dr["dept"] as string, newDeptId);
                }
                db.SubmitChanges();
                Debug.WriteLine("部门 导入完毕！");


                // 导入职位
                sqlStr = "SELECT * FROM userlevel ";
                cmd = new OdbcCommand(sqlStr, conn);
                dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    Guid newPosId = Guid.NewGuid();
                    db.ez_Positions.InsertOnSubmit(
                        new ez_Position()
                        {
                            PosId = newPosId,
                            Priority = (int)dr["pri"],
                            Description = dr["userlevel"] as string,
                        }
                        );
                    positionDict.Add(dr["userlevel"] as string, newPosId);
                }
                db.SubmitChanges();
                Debug.WriteLine("职位 导入完毕！");

                //导入人员
                sqlStr = "SELECT * FROM userinf ";
                cmd = new OdbcCommand(sqlStr, conn);
                dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    string username = dr["username"] as string;
                    string name = dr["name"] as string;
                    Membership.CreateUser(username, "123456", "xx@@@.com");

                    //固定几个User的UserId，供测试用：
                    Guid newUserId = Guid.NewGuid();
                    switch (name)
                    {
                        case "Karin":
                            newUserId = new Guid("877c3323-17a7-42d1-9d75-402ffc894e63");
                            break;
                        case "龚伟":
                            newUserId = new Guid("19f1c421-280f-4935-9980-e469175461c2");
                            break;
                        case "杨裕欣":
                            newUserId = new Guid("0c9d7c0c-04a5-4ae2-97a1-d7bbc38f5c66");
                            break;
                        case "卢春叶":
                            newUserId = new Guid("ce36c495-38cc-4b7e-875e-364ff8e087b5");
                            break;
                        case "杨鑫诚":
                            newUserId = new Guid("37595596-9669-4CC9-B1DB-74F48A31B230");
                            break;
                        case "黄冠":
                            newUserId = new Guid("EC6D5998-1948-4C0B-8987-E690C3F64E8A");
                            break;
                        case "贺旭华":
                            newUserId = new Guid("06F1962D-5B9E-481D-8C5A-0278506B0677");
                            break;
                    }
                    db.ez_UserProfiles.InsertOnSubmit(
                        new ez_UserProfile()
                        {
                            UserId = newUserId,
                            DeptId = deptDict[dr["userdept"] as string],
                            PosId = positionDict[dr["userlevel"] as string],
                            UserName = username,
                            Name = name,
                        }
                        );
                }
                db.SubmitChanges();
                Debug.WriteLine("人员 导入完毕！");
            }
        }


        private void CreateBasicGroups()
        {

            // 建立系统分组
            db.ez_Groups.InsertOnSubmit(
                new ez_Group()
                {
                    GroupId = Guid.NewGuid(),
                    MemberString = "everyone",
                    Description = "所有人",
                    Type = 0, /* Type = 2, 系统组 */
                    Name = "core_everyone"
                });
            db.SubmitChanges();
            Debug.WriteLine("所有人 分组建立完成");


            //建立各部门分组
            var depts = from d in db.ez_Depts
                        select d;
            foreach (var dept in depts)
            {
                List<string> usersInDept = (from u in dept.ez_UserProfiles
                                            select u.UserId.ToString()).ToList();

                Guid newGroupId = Guid.NewGuid();
                db.ez_Groups.InsertOnSubmit(
                    new ez_Group()
                    {
                        GroupId = newGroupId,
                        MemberString = GroupMemeberStrHelper.GetGroupMemberStrFromList(usersInDept, null),
                        Description = dept.DeptName,
                        Type = 1, /* Type = 2, 公司部门分组 */
                        Name = "core_dept" + dept.DeptName,
                    });

                dept.GroupId = newGroupId;
                db.SubmitChanges();
            }

            Debug.WriteLine("各部门分组建立完成");

            // 建立 用户权限组
            Debug.WriteLine("开始建立用户权限组");

            // 建立 Boss 组
            ez_Group bossGroup = new ez_Group()
            {
                GroupId = bossGroupId,
                Description = "公司负责人",
                MemberString = "0c9d7c0c-04a5-4ae2-97a1-d7bbc38f5c66,06F1962D-5B9E-481D-8C5A-0278506B0677",  /* 贺旭华 & 杨裕欣 */
                Type = 2, /* Type = 2, 用户权限组 */
                Name = "core_boss"
            };
            db.ez_Groups.InsertOnSubmit(bossGroup);

            // 建立 人事 组
            ez_Group hrGroup = new ez_Group()
            {
                GroupId = hrGroupId,
                Description = "公司人事管理",
                MemberString = "EC6D5998-1948-4C0B-8987-E690C3F64E8A,ce36c495-38cc-4b7e-875e-364ff8e087b5", /* 黄冠 & 卢春叶 */
                Type = 2,
                Name = "attendance_hr"
            };
            db.ez_Groups.InsertOnSubmit(hrGroup);

            // 建立 普通员工 组
            ez_Group employeeGroup = new ez_Group()
            {
                GroupId = Guid.NewGuid(),
                Description = "公司中的在职员工",
                MemberString = "everyone",
                Type = 2,
                Name = "core_employee"
            };
            db.ez_Groups.InsertOnSubmit(employeeGroup);

            Debug.WriteLine("用户权限组建立完成");
        }


        #region IEzDeskInitial Members

        void IEzDeskInitial.Initialize()
        {
            //清空数据库
            CleanupDatabase();

            //删除Membership中所有注册信息
            ImportBasicDataFromDb();

            // 初始化公司信息等
            InitializeGlobleInfo();

            Debug.WriteLine("正在导入 FeedTemplate 数据");
            InitialFeedsTemplate(FEED_TEMPLATES_FILENAME);
            Debug.WriteLine("导入 FeedTemplate 数据结束");

            //建立分组
            CreateBasicGroups();

            // 建立Permission基本信息
            CreatPermissions();

            // 建立AppFunctions基本信息
            CreateAppFunctions(APP_FUNCTIONS_FILENAME);

            foreach (var init in initials)
            {
                init.Initialize();
            }

            Debug.WriteLine("完成!");
        }

        private void InitializeGlobleInfo()
        {
            Debug.WriteLine("开始添加 Org 信息...");

            db.ez_Organizations.InsertOnSubmit(new ez_Organization() { OrgId = Guid.NewGuid(), Icon = "huaweilogo.png", Title = "上海魏玛", UpdateOn = DateTime.Now });
            db.SubmitChanges();

            Debug.WriteLine("Org 信息添加完成");
        }


        public void AddInitializeModule(IEzDeskInitial initial)
        {
            initials.Add(initial);
        }

        #endregion




        private static void CleanupMembershipData()
        {
            Debug.WriteLine("清除MemberShip数据库");
            MembershipUserCollection users = Membership.GetAllUsers();
            foreach (MembershipUser user in users)
            {
                Membership.DeleteUser(user.UserName);
            }
            Debug.WriteLine("MemberShip用户全部清除!");
        }

        private void CleanupDatabase()
        {
            // 
            db.ez_Recipient_Feeds.DeleteAllOnSubmit(db.ez_Recipient_Feeds);
            db.SubmitChanges();

            //清空Feed
            db.ez_Feeds.DeleteAllOnSubmit(db.ez_Feeds);
            db.SubmitChanges();
            Debug.WriteLine("提醒全部清空!");


            //清空Feed模板
            db.ez_FeedTemplates.DeleteAllOnSubmit(db.ez_FeedTemplates);
            db.SubmitChanges();
            Debug.WriteLine("Feeds模板全部清除!");

            //清空AppDomain列表
            db.ez_AppDomains.DeleteAllOnSubmit(db.ez_AppDomains);
            db.SubmitChanges();
            Debug.WriteLine("AppDomains全部清除!");

            //清空App列表
            db.ez_Apps.DeleteAllOnSubmit(db.ez_Apps);
            db.SubmitChanges();
            Debug.WriteLine("App全部清除!");

            //清空人员
            db.ez_UserProfiles.DeleteAllOnSubmit(db.ez_UserProfiles);
            db.SubmitChanges();
            Debug.WriteLine("人员信息全部清空！");


            //清空部门
            db.ez_Depts.DeleteAllOnSubmit(db.ez_Depts);
            db.SubmitChanges();
            Debug.WriteLine("部门信息已经全部清除!");

            //清空分组
            db.ez_Groups.DeleteAllOnSubmit(db.ez_Groups);
            db.SubmitChanges();
            Debug.WriteLine("分组数据全部清除!");

            //清空职位
            db.ez_Positions.DeleteAllOnSubmit(db.ez_Positions);
            db.SubmitChanges();
            Debug.WriteLine("职位信息已经全部清除!");

            //清空权限
            db.ez_Permissions.DeleteAllOnSubmit(db.ez_Permissions);
            db.SubmitChanges();
            Debug.WriteLine("权限信息已经全部清除!");

            //清空权限_组表
            db.ez_Permission_Groups.DeleteAllOnSubmit(db.ez_Permission_Groups);
            db.SubmitChanges();
            Debug.WriteLine("权限_组信息已经全部清除!");

            //清空AppFunction
            db.ez_AppFunctions.DeleteAllOnSubmit(db.ez_AppFunctions);
            db.SubmitChanges();
            Debug.WriteLine("AppFunction信息已经全部清除!");

            //清空AppFunctionType
            db.ez_AppFunctionTypes.DeleteAllOnSubmit(db.ez_AppFunctionTypes);
            db.SubmitChanges();
            Debug.WriteLine("AppFunctionTypes信息已经全部清除!");

            //清空AppFunction_user
            db.ez_AppFunctionShortcuts.DeleteAllOnSubmit(db.ez_AppFunctionShortcuts);
            db.SubmitChanges();
            Debug.WriteLine("AppFunctionShortcuts信息已经全部清除!");

            //清空Organization
            db.ez_Organizations.DeleteAllOnSubmit(db.ez_Organizations);
            db.SubmitChanges();
            Debug.WriteLine("ez_Organizations信息已经全部清除!");
        }


    }



}
